package com.jse;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashSet;
import java.util.Optional;

public class Fs {

	public static String readString(String path){return readString(Path.of(path),StandardCharsets.UTF_8);}
	public static String readString(String base,String path){
		if(base==null)return readString(path);
		if(base.equals("$")||base.equals("classpath")) {
			return readString(Path.of(Jse.classpath,path),StandardCharsets.UTF_8);
		}else if(base.equals("js")||base.equals("jspath")) {
			return readString(Path.of(Jse.jspath(),path),StandardCharsets.UTF_8);
		}else if(base.equals("webapp")||base.equals("web")) {
			return readString(Path.of(Jse.webapp(),path),StandardCharsets.UTF_8);
		}else if(base.equals("webapps")) {
			return readString(Path.of(Jse.webapps(),path),StandardCharsets.UTF_8);
		}else if(base.equals("dir")) {
			return readString(Path.of(Jse.dir,path),StandardCharsets.UTF_8);
		}else if(base.equals("home")) {
			return readString(Path.of(Jse.home,path),StandardCharsets.UTF_8);
		}
		return readString(Path.of(base,path),StandardCharsets.UTF_8);
	}
	public static String readString(Path path){return readString(path,StandardCharsets.UTF_8);}
	public static String readString(Path path,Charset charset){
		try{return Files.readString(path,charset);}catch(IOException e){throw new RuntimeException(e);}}
	public static byte[] readAllBytes(Path f) {
		try {
			return Files.readAllBytes(f);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
	public static boolean exists(String url){return Files.exists(Path.of(url));}
	public static boolean exists(String base,String url){
		if(base==null)return exists(url);
		return switch (base) {
		case "$","classpath" ->Files.exists(Path.of(Jse.classpath,url));
		case "js","jspath" ->Files.exists(Path.of(Jse.jspath(),url));
		case "web","webapp" ->Files.exists(Path.of(Jse.webapp(),url));
		case "webapps" ->Files.exists(Path.of(Jse.webapps(),url));
		case "dir" ->Files.exists(Path.of(Jse.dir,url));
		default ->Files.exists(Path.of(base,url));};
	}

	public static void write(String path, String s) {
		try{Files.writeString(Path.of(path),s);}catch(IOException e){throw new RuntimeException(e);}}
	public static void write(String path,InputStream in) {
		try(FileOutputStream fos=new FileOutputStream(path)){
			in.transferTo(fos);
		}catch(IOException e){throw new RuntimeException(e);}}
	
	public static long lastModified(String p) {
		return lastModified(Path.of(p));
	}
	public static long lastModified(Path p) {
		try {return Files.getLastModifiedTime(p).toMillis();
		}catch (IOException e) {throw new RuntimeException(e);}
	}
	public static String suffix(String s) {
		if(s==null)return "";
		int index=s.lastIndexOf('.');
		if(index!=-1){return s.substring(index+1);}
		return "";
	}
	public static void mkdirs(String abspath) {
		new File(abspath).mkdirs();
	}
	
	public static boolean delete(Path of) {
		try {
			Files.delete(of);
			return true;
		} catch (IOException e) {
			return false;
		}
	}
	
	public static String mimeType(Object o) {
    	try {
    		if(o instanceof String s) {
        		return Files.probeContentType(Path.of(s.indexOf('.')==-1?"."+s:s));
        	}else if(o instanceof Path p) {
        		return Files.probeContentType(p);
        	}else if(o instanceof File f) {
        		return Files.probeContentType(f.toPath());
        	}
			return Files.probeContentType(Path.of(o.toString()));
		} catch (IOException e) {
			return null;//"application/octet-stream"
		}
    }
	
	public static String mimeType(Object o,String def) {
		return Optional.ofNullable(mimeType(o)).orElse(def);
	}
	
	public static String basePath(String path) {
		int idj=path.lastIndexOf('!');
		if(idj!=-1) {
			path=path.substring(0,idj);
		}
		int idx=path.lastIndexOf('/');
		if(idx!=-1) {
			return path.substring(0, idx);
		}
		return path;
	}
	
	public static boolean isSame(String p1,String p2) {
		try {return Files.isSameFile(Path.of(p1),Path.of(p2));
		} catch (IOException e) {throw new RuntimeException(e);}
	}
	
	public static HashSet<Path> paths(String path,int type) throws IOException {
		return paths(Path.of(path), type);
	}
	/**
	 * 
	 * @param path
	 * @param type -1全部,0文件,1目录
	 * @return
	 * @throws IOException
	 */
	public static HashSet<Path> paths(Path root,int type){
		HashSet<Path> paths=new HashSet<Path>();
		try {
			if(Files.exists(root))
			Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
				@Override
				public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
					if(type!=0)paths.add(dir);
					return super.preVisitDirectory(dir, attrs);
				}
				@Override
				public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
					if(type<1)paths.add(file);
					return super.visitFile(file, attrs);
				}
			});
			return paths;
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
	
	public static void main(String[] args) {
		try {
			System.out.println(paths("D:\\tomcat",1));
		} catch (Throwable e) {
			String s=Errs.message(e);
			System.err.println(s);
		}finally {
			System.out.println("finsh");
		}
	}
}
